home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Taifun / Taifun 121 (1990-02-15)(Ossowski, Stefan)(DE)(PD).zip / Taifun 121 (1990-02-15)(Ossowski, Stefan)(DE)(PD).adf / DiskSpeed / DiskSpeed.c < prev    next >
C/C++ Source or Header  |  1989-11-08  |  23KB  |  808 lines

  1. /*
  2.  *                          DiskSpeed v1.0
  3.  *                                by
  4.  *                           Michael Sinz
  5.  *
  6.  *             Copyright (c) 1989 by MKSoft Development
  7.  *
  8.  *
  9.  * Yes, this is yet another disk speed testing program, but with a few
  10.  * differences.  It was designed to give the most accurate results of the
  11.  * true disk performance in the system.  For this reason many of
  12.  * DiskSpeed's results may look either lower or higher than current disk
  13.  * performance tests.
  14.  *
  15.  * This program was thrown together in a few hours because I needed more
  16.  * accurate and consistant results for disk performance as seen from the
  17.  * application's standpoint.  This program has now served its purpose and
  18.  * I am now giving it to the rest of the Amiga world to play with as long
  19.  * as all of the files remain together in unmodified form.  (That is, the
  20.  * files DiskSpeed, DiskSpeed.info, DiskSpeed.c, DiskSpeed.doc, and
  21.  * MakeFile)
  22.  *
  23.  ******************************************************************************
  24.  *                                          *
  25.  *    Reading legal mush can turn your bain into guacamole!              *
  26.  *                                          *
  27.  *        So here is some of that legal mush:                  *
  28.  *                                          *
  29.  * Permission is hereby granted to distribute this program's source          *
  30.  * executable, and documentation for non-comercial purposes, so long as the   *
  31.  * copyright notices are not removed from the sources, executable or          *
  32.  * documentation.  This program may not be distributed for a profit without   *
  33.  * the express written consent of the author Michael Sinz.              *
  34.  *                                          *
  35.  * This program is not in the public domain.                      *
  36.  *                                          *
  37.  * Fred Fish is expressly granted permission to distribute this program's     *
  38.  * source and executable as part of the "Fred Fish freely redistributable     *
  39.  * Amiga software library."                              *
  40.  *                                          *
  41.  * Permission is expressly granted for this program and it's source to be     *
  42.  * distributed as part of the Amicus Amiga software disks, and the          *
  43.  * First Amiga User Group's Hot Mix disks.                      *
  44.  *                                          *
  45.  ******************************************************************************
  46.  */
  47.  
  48. #include    <EXEC/Types.h>
  49. #include    <EXEC/Memory.h>
  50. #include    <Intuition/Intuition.h>
  51. #include    <Libraries/DOS.h>
  52. #include    <Libraries/DOSextens.h>
  53. #include    <Devices/Timer.h>
  54.  
  55. #include    <PROTO/All.h>
  56.  
  57. #include    <string.h>
  58.  
  59. extern    struct    IntuitionBase    *IntuitionBase;
  60.     struct    Library        *TimerBase;
  61.  
  62. #define    TIMESCALER        256L
  63. #define    SEEK_READ_SIZE        64L
  64. #define    REQ_GAD            7
  65. #define    TEXT_BUFFER_SIZE    1024L
  66.  
  67. static char FileUnit[8]    ="files/s";
  68. static char Text1[8]    ="bytes/s";
  69. static char Text2[12]    ="32768 byte:";
  70. static char Text3[11]    ="4096 byte:";
  71. static char Text4[10]    ="512 byte:";
  72. static char Text5[16]    ="Raw Write Speed";
  73. static char Text6[15]    ="Raw Read Speed";
  74. static char Text7[13]    ="Seek & Read:";
  75. static char Text8[16]    ="Directory Scan:";
  76. static char Text9[13]    ="File Delete:";
  77. static char Text10[13]    ="File Create:";
  78. static char Text11[7]    ="Drive:";
  79.  
  80. static char MenuText1[12]    ="Version 1.0";
  81. static char MenuText2[17]    ="Copyright © 1989";
  82. static char MenuText3[16]    ="By Michael Sinz";
  83. static char MenuText4[5]    ="Test";
  84. static char MenuText5[5]    ="Save";
  85. static char MenuText6[6]    ="Print";
  86. static char MenuText7[23]    ="MKSoft Disk Speed Test";
  87. static char MenuText8[8]    ="Project";
  88. static char MenuText9[5]    ="Quit";
  89.  
  90. static char ErrorText1[28]    ="Can't create test directory";
  91. static char ErrorText2[16]    ="Bad device name";
  92. static char ErrorText3[24]    ="Can't open results file";
  93. static char ErrorText4[19]    ="Can't open printer";
  94.  
  95. static char WindowText[60]    ="Disk Speed Test 1.0  Copyright © 1989 by MKSoft Development";
  96. static char WorkingText[12]    =" Working...";
  97.  
  98. static char PrinterFile[5]    ="PRT:";
  99. static char ResultFile[18]    ="DiskSpeed.Results";
  100. static char DirectoryName[22]    =" Disk Test Directory ";
  101. static char FileNameRoot[22]    =" -- DiskTest File -- ";
  102.  
  103. static char File_Create[12];
  104. static char File_Delete[12];
  105. static char Directory_Scan[12];
  106. static char Seek_And_Read[12];
  107. static char Read_512[12];
  108. static char Read_4096[12];
  109. static char Read_32768[12];
  110. static char Write_512[12];
  111. static char Write_4096[12];
  112. static char Write_32768[12];
  113.  
  114. static UBYTE Device[32];
  115.  
  116. static char fontnam[11]    ="topaz.font";
  117.  
  118. static struct TextAttr TOPAZ60    ={fontnam,TOPAZ_SIXTY,0,0};
  119. static struct TextAttr TOPAZ80    ={fontnam,TOPAZ_EIGHTY,0,0};
  120.  
  121.  
  122. static SHORT BorderVectors1[10]    ={0,0,230,0,230,40,0,40,0,0};
  123. static SHORT BorderVectors[10]    ={0,0,177,0,177,9,0,9,0,0};
  124.  
  125. static struct Border Border6    ={4-56,24-13,1,0,JAM1,5,BorderVectors1,NULL};
  126. static struct Border Border5    ={5-56,25-13,2,0,JAM1,5,BorderVectors1,&Border6};
  127. static struct Border Border4    ={4-56,67-13,1,0,JAM1,5,BorderVectors1,&Border5};
  128. static struct Border Border3    ={5-56,68-13,2,0,JAM1,5,BorderVectors1,&Border4};
  129. static struct Border Border2    ={4-56,111-13,1,0,JAM1,5,BorderVectors1,&Border3};
  130. static struct Border Border1    ={5-56,112-13,2,0,JAM1,5,BorderVectors1,&Border2};
  131. static struct Border Border    ={-1,-1,1,0,JAM1,5,BorderVectors,&Border1};
  132.  
  133. static struct IntuiText IText25    ={1,0,JAM2,48,129,&TOPAZ60,Write_32768,NULL};
  134. static struct IntuiText IText24    ={1,0,JAM2,48,120,&TOPAZ60,Write_4096,&IText25};
  135. static struct IntuiText IText23    ={1,0,JAM2,48,111,&TOPAZ60,Write_512,&IText24};
  136. static struct IntuiText IText22    ={1,0,JAM2,48,85,&TOPAZ60,Read_32768,&IText23};
  137. static struct IntuiText IText21    ={1,0,JAM2,48,76,&TOPAZ60,Read_4096,&IText22};
  138. static struct IntuiText IText20    ={1,0,JAM2,48,67,&TOPAZ60,Read_512,&IText21};
  139. static struct IntuiText IText19    ={1,0,JAM2,78,41,&TOPAZ80,Seek_And_Read,&IText20};
  140. static struct IntuiText IText18    ={1,0,JAM2,78,23,&TOPAZ80,Directory_Scan,&IText19};
  141. static struct IntuiText IText17    ={1,0,JAM2,78,32,&TOPAZ80,File_Delete,&IText18};
  142. static struct IntuiText IText16    ={1,0,JAM2,78,14,&TOPAZ80,File_Create,&IText17};
  143.  
  144. static struct IntuiText IText15    ={3,0,JAM2,120,101,&TOPAZ80,Text1,&IText16};
  145. static struct IntuiText IText14    ={3,0,JAM2,120,57,&TOPAZ80,Text1,&IText15};
  146. static struct IntuiText IText13    ={1,0,JAM2,-49,129,&TOPAZ80,Text2,&IText14};
  147. static struct IntuiText IText12    ={1,0,JAM2,-41,120,&TOPAZ80,Text3,&IText13};
  148. static struct IntuiText IText11    ={1,0,JAM2,-33,111,&TOPAZ80,Text4,&IText12};
  149. static struct IntuiText IText10    ={1,0,JAM2,-49,101,&TOPAZ60,Text5,&IText11};
  150. static struct IntuiText IText9    ={1,0,JAM2,-49,85,&TOPAZ80,Text2,&IText10};
  151. static struct IntuiText IText8    ={1,0,JAM2,-41,76,&TOPAZ80,Text3,&IText9};
  152. static struct IntuiText IText7    ={1,0,JAM2,-33,67,&TOPAZ80,Text4,&IText8};
  153. static struct IntuiText IText6    ={1,0,JAM2,-49,57,&TOPAZ60,Text6,&IText7};
  154. static struct IntuiText IText5    ={1,0,JAM2,-50,41,&TOPAZ80,Text7,&IText6};
  155. static struct IntuiText IText4    ={1,0,JAM2,-49,23,&TOPAZ80,Text8,&IText5};
  156. static struct IntuiText IText3    ={1,0,JAM2,-49,32,&TOPAZ80,Text9,&IText4};
  157. static struct IntuiText IText2    ={1,0,JAM2,-49,14,&TOPAZ80,Text10,&IText3};
  158. static struct IntuiText IText1    ={1,0,JAM2,-50,0,&TOPAZ80,Text11,&IText2};
  159.  
  160. static struct IntuiText MText1    ={3,1,COMPLEMENT,61,1,&TOPAZ80,MenuText1,NULL};
  161. static struct IntuiText MText2    ={3,1,COMPLEMENT,41,1,&TOPAZ80,MenuText2,NULL};
  162. static struct IntuiText MText3    ={3,1,COMPLEMENT,45,1,&TOPAZ80,MenuText3,NULL};
  163.  
  164. static struct IntuiText MText4    ={3,1,COMPLEMENT,0,1,&TOPAZ80,MenuText4,NULL};
  165. static struct IntuiText MText5    ={3,1,COMPLEMENT,0,1,&TOPAZ80,MenuText5,NULL};
  166. static struct IntuiText MText6    ={3,1,COMPLEMENT,0,1,&TOPAZ80,MenuText6,NULL};
  167. static struct IntuiText MText7    ={3,1,COMPLEMENT,0,1,&TOPAZ80,MenuText9,NULL};
  168.  
  169. static struct StringInfo GadgetSInfo    ={Device,NULL,0,31,0,0,0,0,0,0,0,0,NULL};
  170.  
  171. static struct Gadget MyGadget    ={NULL,56,13,176,8,NULL,RELVERIFY,STRGADGET,(APTR)&Border,NULL,&IText1,NULL,(APTR)&GadgetSInfo,NULL,NULL};
  172.  
  173. static struct MenuItem MenuItem3    ={NULL,0,20,216,10,ITEMTEXT|ITEMENABLED|HIGHNONE,0,(APTR)&MText1,NULL,NULL,NULL,MENUNULL};
  174. static struct MenuItem MenuItem2    ={&MenuItem3,0,10,216,10,ITEMTEXT|ITEMENABLED|HIGHNONE,0,(APTR)&MText2,NULL,NULL,NULL,MENUNULL};
  175. static struct MenuItem MenuItem1    ={&MenuItem2,0,0,216,10,ITEMTEXT|ITEMENABLED|HIGHNONE,0,(APTR)&MText3,NULL,NULL,NULL,MENUNULL};
  176.  
  177. static struct MenuItem MenuItem7    ={NULL,0,45,80,10,COMMSEQ|ITEMTEXT|ITEMENABLED|HIGHCOMP,0,(APTR)&MText7,NULL,'Q',NULL,MENUNULL};
  178. static struct MenuItem MenuItem6    ={&MenuItem7,0,30,80,10,COMMSEQ|ITEMTEXT|ITEMENABLED|HIGHCOMP,0,(APTR)&MText6,NULL,'P',NULL,MENUNULL};
  179. static struct MenuItem MenuItem5    ={&MenuItem6,0,15,80,10,COMMSEQ|ITEMTEXT|ITEMENABLED|HIGHCOMP,0,(APTR)&MText5,NULL,'S',NULL,MENUNULL};
  180. static struct MenuItem MenuItem4    ={&MenuItem5,0,0,80,10,COMMSEQ|ITEMTEXT|ITEMENABLED|HIGHCOMP,0,(APTR)&MText4,NULL,'T',NULL,MENUNULL};
  181.  
  182. static struct Menu Menu2    ={NULL,80,0,220,0,MENUENABLED,MenuText7,&MenuItem1};
  183. static struct Menu MyMenu    ={&Menu2,0,0,70,0,MENUENABLED,MenuText8,&MenuItem4};
  184.  
  185. static struct NewWindow NewWindowStructure    ={110,11,240,156,0,1,GADGETUP|CLOSEWINDOW|ACTIVEWINDOW|MENUPICK,WINDOWDRAG|WINDOWDEPTH|WINDOWCLOSE|ACTIVATE|NOCAREREFRESH,&MyGadget,NULL,WindowText,NULL,NULL,0,0,0,0,WBENCHSCREEN};
  186.  
  187. static SHORT MyReqVec[10]        ={0,0, 0,40, 231,40, 231,0, 0,0};
  188. static struct Border MyReqBorder    ={0,0,2,0,JAM1,5,MyReqVec,NULL};
  189. static struct IntuiText MyReqText    ={0,1,JAM1,0,16,&TOPAZ80,NULL,NULL};
  190. static struct Gadget MyReqGadget    ={NULL,0,0,232,41,GADGHCOMP,RELVERIFY,BOOLGADGET|REQGADGET,(APTR)&MyReqBorder,NULL,&MyReqText,NULL,NULL,REQ_GAD,NULL};
  191.  
  192. /*
  193.  * This does a requester on the window to tell the user something...
  194.  */
  195. VOID TellUser(struct Window *Window,char *Text)
  196. {
  197. register    struct    Requester    *myReq;
  198. register    struct    IntuiMessage    *msg;
  199. register        SHORT        flag=TRUE;
  200.  
  201.     if (myReq=AllocMem(sizeof(struct Requester),MEMF_PUBLIC|MEMF_CLEAR))
  202.     {
  203.         myReq->LeftEdge=3;
  204.         myReq->TopEdge=24;
  205.         myReq->Width=232;
  206.         myReq->Height=41;
  207.         myReq->BackFill=1;    /* Pen colour 1 */
  208.  
  209.         myReq->ReqGadget=&MyReqGadget;
  210.  
  211.         MyReqText.LeftEdge=116-(4*strlen(Text));
  212.         MyReqText.IText=Text;
  213.  
  214.         Request(myReq,Window);
  215.         while (flag)
  216.         {
  217.             WaitPort(Window->UserPort);
  218.             while (msg=(struct IntuiMessage *)GetMsg(Window->UserPort))
  219.             {
  220.                 if (msg->Class==GADGETUP)
  221.                 {
  222.                     if (((struct Gadget *)(msg->IAddress))->GadgetID==REQ_GAD) flag=FALSE;
  223.                 }
  224.                 ReplyMsg((struct Message *)msg);
  225.             }
  226.         }
  227.         EndRequest(myReq,Window);
  228.  
  229.         FreeMem(myReq,sizeof(struct Requester));
  230.     }
  231. }
  232.  
  233. /*
  234.  * Returns FALSE if the user clicked on the CLOSE gadget...
  235.  */
  236. SHORT Check_Quit(struct Window *Window)
  237. {
  238. register    struct    IntuiMessage    *msg;
  239. register        SHORT        flag=TRUE;
  240.  
  241.     while(msg=(struct IntuiMessage *)GetMsg(Window->UserPort))
  242.     {
  243.         if (msg->Class==CLOSEWINDOW) flag=FALSE;
  244.         ReplyMsg((struct Message *)msg);
  245.     }
  246.     return(flag);
  247. }
  248.  
  249. /*
  250.  * Clears a string entry to spaces...
  251.  */
  252. VOID Clear_Entry(char *String)
  253. {
  254. register    SHORT    t;
  255.  
  256.     for (t=0;t<11;t++) String[t]=' ';
  257.     String[11]='\0';
  258. }
  259.  
  260. /*
  261.  * Sets a string entry to the value passed and does a RefreshGadgets()
  262.  * to display it...
  263.  */
  264. VOID Set_Entry(char *String,LONG Value,struct Window *Window)
  265. {
  266. register    SHORT    t;
  267. register    SHORT    tmp;
  268.  
  269.     t=11;
  270.     while (Value)
  271.     {
  272.         tmp=Value%10;
  273.         Value=Value/10;
  274.         String[--t]=(char)(tmp)+'0';
  275.     }
  276.     if (!String[t]) String[--t]='0';
  277.     RefreshGadgets(&MyGadget,Window,NULL);
  278. }
  279.  
  280. /*
  281.  * This gets the starting time...
  282.  */
  283. VOID Timer_Start(struct Window *Window)
  284. {
  285. register    struct    timerequest    *Time_Req;
  286.  
  287.     Time_Req=(struct timerequest *)Window->UserData;
  288.  
  289.     Time_Req->tr_node.io_Command=TR_GETSYSTIME;
  290.     Time_Req->tr_node.io_Flags=IOF_QUICK;
  291.     DoIO((struct IORequest *)Time_Req);
  292. }
  293.  
  294. /*
  295.  * This gets the ending time and finds out what the per second speed is...
  296.  * It also does a RefreshGadgets() to display the text...
  297.  */
  298. VOID Timer_Stop(struct Window *Window,char *Text,LONG Number)
  299. {
  300. register    struct    timerequest    *Time_Req;
  301. register        LONG        Value;
  302.         struct    timeval        StartTime;
  303.  
  304.     Time_Req=(struct timerequest *)Window->UserData;
  305.  
  306.     StartTime=Time_Req->tr_time;    /* Store start time... */
  307.  
  308.     Time_Req->tr_node.io_Command=TR_GETSYSTIME;
  309.     Time_Req->tr_node.io_Flags=IOF_QUICK;
  310.     DoIO((struct IORequest *)Time_Req);
  311.  
  312.     SubTime(&Time_Req->tr_time,&StartTime);
  313.  
  314.     /* Now calculate Value based on Number and the time... */
  315.     Value=(Number*TIMESCALER) /
  316.         (    (Time_Req->tr_time.tv_secs*TIMESCALER) +
  317.             (Time_Req->tr_time.tv_micro/(1000000L/TIMESCALER))
  318.         );
  319.  
  320.     Set_Entry(Text,Value,Window);
  321. }
  322.  
  323. /*
  324.  * File create test...
  325.  * This creates a bunch of files in our test directory...
  326.  * The delete test deletes these files...
  327.  */
  328. VOID Do_FileCreate_Test(struct Window *Window)
  329. {
  330. register    char    *t1;
  331. register    char    *t2;
  332. register    BPTR    file;
  333. register    LONG    count=0;
  334.  
  335.     t1=FileNameRoot+1;
  336.     t2=t1+1;
  337.  
  338.     Timer_Start(Window);
  339.     for (*t1='A';*t1<'Q';(*t1)++) for (*t2='A';*t2<'Q';(*t2)++)
  340.     {
  341.         if (file=Open(FileNameRoot,MODE_NEWFILE)) Close(file);
  342.         count++;
  343.     }
  344.     Timer_Stop(Window,File_Create,count);
  345. }
  346.  
  347. /*
  348.  * Directory scan test...  This is done by scanning the directory we
  349.  * just created in the create test... (Twice...)
  350.  */
  351. VOID Do_DirScan_Test(struct Window *Window)
  352. {
  353. register    struct    FileInfoBlock    *FIB;
  354. register        BPTR        lock;
  355. register        LONG        count=0;
  356.  
  357.     lock=CurrentDir(NULL);    /* Get our directory lock... */
  358.     if (FIB=AllocMem(sizeof(struct FileInfoBlock),MEMF_PUBLIC))
  359.     {
  360.         Timer_Start(Window);
  361.         Examine(lock,FIB);
  362.         while (ExNext(lock,FIB)) count++;
  363.         Examine(lock,FIB);
  364.         while (ExNext(lock,FIB)) count++;
  365.         Timer_Stop(Window,Directory_Scan,count);
  366.  
  367.         FreeMem(FIB,sizeof(struct FileInfoBlock));
  368.     }
  369.     CurrentDir(lock);    /* Return the locked directory... */
  370. }
  371.  
  372. /*
  373.  * File delete test...  We delete the files created in the create test...
  374.  */
  375. VOID Do_FileDelete_Test(struct Window *Window)
  376. {
  377. register    char    *t1;
  378. register    char    *t2;
  379. register    LONG    count=0;
  380.  
  381.     t1=FileNameRoot+1;
  382.     t2=t1+1;
  383.  
  384.     Timer_Start(Window);
  385.     for (*t1='A';*t1<'Q';(*t1)++) for (*t2='A';*t2<'Q';(*t2)++)
  386.     {
  387.         DeleteFile(FileNameRoot);
  388.         count++;
  389.     }
  390.     Timer_Stop(Window,File_Delete,count);
  391. }
  392.  
  393. /*
  394.  * This does the seek/read test...
  395.  */
  396. VOID Do_SeekRead_Test(struct Window *Window,char *Buffer,BPTR bigfile)
  397. {
  398. register    short    t;
  399. register    LONG    count=0;
  400. register    LONG    pos;
  401.  
  402.     Timer_Start(Window);
  403.     for (t=0;t<150;t++)
  404.     {
  405.         Seek(bigfile,0L,OFFSET_BEGINNING);
  406.         Read(bigfile,Buffer,SEEK_READ_SIZE);
  407.         count++;
  408.  
  409.         pos=Seek(bigfile,-(2*SEEK_READ_SIZE),OFFSET_END);
  410.         Read(bigfile,Buffer,SEEK_READ_SIZE);
  411.         count++;
  412.  
  413.         Seek(bigfile,-(pos>>1),OFFSET_CURRENT);
  414.         Read(bigfile,Buffer,SEEK_READ_SIZE);
  415.         count++;
  416.     }
  417.     Timer_Stop(Window,Seek_And_Read,count);
  418. }
  419.  
  420. /*
  421.  * This routine does the write timings...
  422.  * To reduce the number of Seek() commands, the complete file is written
  423.  * multiple times in a loop...
  424.  */
  425. VOID Do_Write_Test(char *Text,LONG Size,struct Window *Window,char *Buffer,BPTR bigfile)
  426. {
  427. register    short    t;
  428. register    short    x;
  429. register    LONG    count=0;
  430. register    LONG    numread;
  431.  
  432.     numread=Seek(bigfile,0L,OFFSET_END)/Size;
  433.  
  434.     Timer_Start(Window);
  435.     for (t=0;t<6;t++)
  436.     {
  437.         Seek(bigfile,0L,OFFSET_BEGINNING);
  438.         for (x=0;x<numread;x++) count+=Write(bigfile,Buffer,Size);
  439.     }
  440.     Timer_Stop(Window,Text,count);
  441. }
  442.  
  443. /*
  444.  * This routine does the read timings...
  445.  * To reduce the number of Seek() commands, the complete file is read
  446.  * multiple times in a loop...
  447.  */
  448. VOID Do_Read_Test(char *Text,LONG Size,struct Window *Window,char *Buffer,BPTR bigfile)
  449. {
  450. register    short    t;
  451. register    short    x;
  452. register    LONG    count=0;
  453. register    LONG    numread;
  454.  
  455.     numread=Seek(bigfile,0L,OFFSET_END)/Size;
  456.  
  457.     Timer_Start(Window);
  458.     for (t=0;t<12;t++)
  459.     {
  460.         Seek(bigfile,0L,OFFSET_BEGINNING);
  461.         for (x=0;x<numread;x++) count+=Read(bigfile,Buffer,Size);
  462.     }
  463.     Timer_Stop(Window,Text,count);
  464. }
  465.  
  466. /*
  467.  * This is the master test routine...  It calles the ones above...
  468.  */
  469. VOID Do_Disk_Test(struct Window *Window)
  470. {
  471. register    BPTR    lock;
  472. register    BPTR    mydir;
  473. register    BPTR    bigfile;
  474. register    SHORT    flag=TRUE;
  475. register    BYTE    *Buffer;
  476.  
  477.     if (lock=Lock(Device,ACCESS_READ))
  478.     {
  479.         lock=CurrentDir(lock);
  480.         if (mydir=CreateDir(DirectoryName))
  481.         {
  482.             mydir=CurrentDir(mydir);
  483.  
  484.             Clear_Entry(File_Create);
  485.             Clear_Entry(File_Delete);
  486.             Clear_Entry(Directory_Scan);
  487.             Clear_Entry(Seek_And_Read);
  488.             Clear_Entry(Read_512);
  489.             Clear_Entry(Read_4096);
  490.             Clear_Entry(Read_32768);
  491.             Clear_Entry(Write_512);
  492.             Clear_Entry(Write_4096);
  493.             Clear_Entry(Write_32768);
  494.             RefreshGadgets(&MyGadget,Window,NULL);
  495.  
  496.             if (flag&=Check_Quit(Window))
  497.             {
  498.                 Do_FileCreate_Test(Window);
  499.                 if (flag&=Check_Quit(Window)) Do_DirScan_Test(Window);
  500.                 Do_FileDelete_Test(Window);
  501.             }
  502.             if (flag&=Check_Quit(Window))
  503.             {
  504.                 if (bigfile=Open(FileNameRoot,MODE_NEWFILE))
  505.                 {
  506.                     if (Buffer=AllocMem(32768L,MEMF_PUBLIC))
  507.                     {
  508.                         for (flag=8;flag--;flag>1) if (Write(bigfile,Buffer,32768L)<32768L) flag=FALSE;
  509.  
  510.                         if (flag&=Check_Quit(Window)) Do_SeekRead_Test(Window,Buffer,bigfile);
  511.  
  512.                         if (flag&=Check_Quit(Window)) Do_Read_Test(Read_512,512L,Window,Buffer,bigfile);
  513.                         if (flag&=Check_Quit(Window)) Do_Read_Test(Read_4096,4096L,Window,Buffer,bigfile);
  514.                         if (flag&=Check_Quit(Window)) Do_Read_Test(Read_32768,32768L,Window,Buffer,bigfile);
  515.  
  516.                         if (flag&=Check_Quit(Window)) Do_Write_Test(Write_512,512L,Window,Buffer,bigfile);
  517.                         if (flag&=Check_Quit(Window)) Do_Write_Test(Write_4096,4096L,Window,Buffer,bigfile);
  518.                         if (flag&=Check_Quit(Window)) Do_Write_Test(Write_32768,32768L,Window,Buffer,bigfile);
  519.  
  520.                         FreeMem(Buffer,32768L);
  521.                     }
  522.                     Close(bigfile);
  523.                     DeleteFile(FileNameRoot);
  524.                 }
  525.             }
  526.  
  527.             mydir=CurrentDir(mydir);
  528.             UnLock(mydir);
  529.             DeleteFile(DirectoryName);
  530.         }
  531.         else
  532.         {    /* Tell user he messed up... */
  533.             TellUser(Window,ErrorText1);
  534.         }
  535.  
  536.         lock=CurrentDir(lock);
  537.         UnLock(lock);
  538.     }
  539.     else
  540.     {    /* Tell user he messed up... */
  541.         TellUser(Window,ErrorText2);
  542.     }
  543. }
  544.  
  545. /*
  546.  * This define is for the Write_Results routine...
  547.  */
  548. #define    MYCAT(z,y,x)    for (y=x;*y;*z++=*y++)
  549. #define    MYCATNEWLINE(x)    *x++='\n'
  550. #define    MYCATTAB(x)    *x++='\t'
  551. #define    MYCATSPACE(x)    *x++=' '
  552.  
  553. /*
  554.  * This routine builds a string of the results and then writes it to
  555.  * the file passed...
  556.  */
  557. VOID Write_Results(BPTR TheFile)
  558. {
  559. register    char    *t;
  560. register    char    *h;
  561. register    char    *Buffer;
  562.  
  563.     if (t=Buffer=AllocMem(TEXT_BUFFER_SIZE,MEMF_PUBLIC|MEMF_CLEAR))
  564.     {
  565.         
  566. /* Title and device name */
  567.         MYCATNEWLINE(t);
  568.         MYCAT(t,h,WindowText);
  569.         MYCATNEWLINE(t);
  570.         MYCATNEWLINE(t);
  571.         MYCAT(t,h,Text11);
  572.         MYCATTAB(t);
  573.         MYCAT(t,h,Device);
  574.         MYCATNEWLINE(t);
  575.         MYCATNEWLINE(t);
  576.  
  577. /* File Create */
  578.         MYCAT(t,h,Text10);
  579.         MYCATTAB(t);
  580.         MYCAT(t,h,File_Create);
  581.         MYCATSPACE(t);
  582.         MYCAT(t,h,FileUnit);
  583.         MYCATNEWLINE(t);
  584.  
  585. /* File Delete */
  586.         MYCAT(t,h,Text9);
  587.         MYCATTAB(t);
  588.         MYCAT(t,h,File_Delete);
  589.         MYCATSPACE(t);
  590.         MYCAT(t,h,FileUnit);
  591.         MYCATNEWLINE(t);
  592.  
  593.         MYCATNEWLINE(t);
  594.  
  595. /* Directory Scan */
  596.         MYCAT(t,h,Text8);
  597.         MYCATTAB(t);
  598.         MYCAT(t,h,Directory_Scan);
  599.         MYCATSPACE(t);
  600.         MYCAT(t,h,FileUnit);
  601.         MYCATNEWLINE(t);
  602.  
  603.         MYCATNEWLINE(t);
  604.  
  605. /* Seek and Read */
  606.         MYCAT(t,h,Text7);
  607.         MYCATTAB(t);
  608.         MYCAT(t,h,Seek_And_Read);
  609.         MYCATNEWLINE(t);
  610.         MYCATNEWLINE(t);
  611.  
  612. /* Read 512 */
  613.         MYCAT(t,h,Text6);
  614.         MYCATTAB(t);
  615.         MYCAT(t,h,Text4);
  616.         MYCATTAB(t);
  617.         MYCAT(t,h,Read_512);
  618.         MYCATSPACE(t);
  619.         MYCAT(t,h,Text1);
  620.         MYCATNEWLINE(t);
  621.  
  622. /* Read 4096 */
  623.         MYCAT(t,h,Text6);
  624.         MYCATTAB(t);
  625.         MYCAT(t,h,Text3);
  626.         MYCATTAB(t);
  627.         MYCAT(t,h,Read_4096);
  628.         MYCATSPACE(t);
  629.         MYCAT(t,h,Text1);
  630.         MYCATNEWLINE(t);
  631.  
  632. /* Read 32768 */
  633.         MYCAT(t,h,Text6);
  634.         MYCATTAB(t);
  635.         MYCAT(t,h,Text2);
  636.         MYCATTAB(t);
  637.         MYCAT(t,h,Read_32768);
  638.         MYCATSPACE(t);
  639.         MYCAT(t,h,Text1);
  640.         MYCATNEWLINE(t);
  641.  
  642.         MYCATNEWLINE(t);
  643.  
  644. /* Write 512 */
  645.         MYCAT(t,h,Text5);
  646.         MYCATTAB(t);
  647.         MYCAT(t,h,Text4);
  648.         MYCATTAB(t);
  649.         MYCAT(t,h,Write_512);
  650.         MYCATSPACE(t);
  651.         MYCAT(t,h,Text1);
  652.         MYCATNEWLINE(t);
  653.  
  654. /* Write 4096 */
  655.         MYCAT(t,h,Text5);
  656.         MYCATTAB(t);
  657.         MYCAT(t,h,Text3);
  658.         MYCATTAB(t);
  659.         MYCAT(t,h,Write_4096);
  660.         MYCATSPACE(t);
  661.         MYCAT(t,h,Text1);
  662.         MYCATNEWLINE(t);
  663.  
  664. /* Write 32768 */
  665.         MYCAT(t,h,Text5);
  666.         MYCATTAB(t);
  667.         MYCAT(t,h,Text2);
  668.         MYCATTAB(t);
  669.         MYCAT(t,h,Write_32768);
  670.         MYCATSPACE(t);
  671.         MYCAT(t,h,Text1);
  672.         MYCATNEWLINE(t);
  673.  
  674. /* End of buffer... */
  675.         MYCATNEWLINE(t);
  676.         MYCATNEWLINE(t);
  677.  
  678. /* Now, all we have to do is write the sucker... */
  679.         Write(TheFile,Buffer,t-Buffer);
  680.  
  681.         FreeMem(Buffer,TEXT_BUFFER_SIZE);
  682.     }
  683. }
  684.  
  685. /*
  686.  * This function will open the file, append to the end of it the
  687.  * test results and close it...
  688.  */
  689. VOID Save_To_File(struct Window *Window)
  690. {
  691. register    BPTR    TheFile;
  692.  
  693.  
  694.     TheFile=Open(ResultFile,MODE_OLDFILE);
  695.     if (!TheFile) TheFile=Open(ResultFile,MODE_NEWFILE);
  696.     if (TheFile)
  697.     {
  698.         Seek(TheFile,0L,OFFSET_END);
  699.         Write_Results(TheFile);
  700.         Close(TheFile);
  701.     }
  702.     else
  703.     {    /* Tell the user the file did not open... */
  704.         TellUser(Window,ErrorText3);
  705.     }
  706. }
  707.  
  708. /*
  709.  * This function will open the printer, append to the end of it the
  710.  * test results and close it...
  711.  */
  712. VOID Save_To_Printer(struct Window *Window)
  713. {
  714. register    BPTR    TheFile;
  715.  
  716.     if (TheFile=Open(PrinterFile,MODE_NEWFILE))
  717.     {
  718.         Seek(TheFile,0L,OFFSET_END);
  719.         Write_Results(TheFile);
  720.         Close(TheFile);
  721.     }
  722.     else
  723.     {    /* Tell the user the file did not open... */
  724.         TellUser(Window,ErrorText4);
  725.     }
  726. }
  727.  
  728. VOID main(VOID)
  729. {
  730. register    struct    Window        *Window;
  731. register    struct    IntuiMessage    *msg;
  732. register    struct    timerequest    *Time_Req;
  733. register        SHORT        QuitFlag=0;
  734. register        USHORT        thismenu;
  735. register    struct    Process        *pr;
  736. register        APTR        Old_WindowPtr;
  737.  
  738.     pr=(struct Process *)FindTask(NULL);
  739.     Old_WindowPtr=pr->pr_WindowPtr;
  740.     pr->pr_WindowPtr=(APTR)(-1);
  741.  
  742.     if (Time_Req=AllocMem(sizeof(struct timerequest),MEMF_PUBLIC|MEMF_CLEAR))
  743.     {
  744.         if (IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",33L))
  745.         {
  746.             if (!OpenDevice(TIMERNAME,UNIT_VBLANK,(struct IORequest *)Time_Req,NULL))
  747.             {
  748.                 Time_Req->tr_node.io_Message.mn_ReplyPort=&(pr->pr_MsgPort);
  749.                 TimerBase=(struct Library *)Time_Req->tr_node.io_Device;
  750.                 if (Window=OpenWindow(&NewWindowStructure))
  751.                 {
  752.                     SetWindowTitles(Window,WindowText,WindowText);
  753.                     Window->UserData=(BYTE *)Time_Req;
  754.                     SetMenuStrip(Window,&MyMenu);
  755.                     while (!QuitFlag)
  756.                     {
  757.                         WaitPort(Window->UserPort);
  758.                         while (msg=(struct IntuiMessage *)GetMsg(Window->UserPort))
  759.                         {
  760.                             if (msg->Class==CLOSEWINDOW) QuitFlag=TRUE;
  761.                             else if (msg->Class==ACTIVEWINDOW) ActivateGadget(&MyGadget,Window,NULL);
  762.                             else if (msg->Class==MENUPICK)
  763.                             {
  764.                                 OffGadget(&MyGadget,Window,NULL);
  765.                                 ClearMenuStrip(Window);
  766.                                 SetWindowTitles(Window,WorkingText,WindowText);
  767.                                 thismenu=msg->Code;
  768.                                 while (MENUNULL!=thismenu)
  769.                                 {
  770.                                     if (0==MENUNUM(thismenu))
  771.                                     {
  772.                                         switch (ITEMNUM(thismenu))
  773.                                         {
  774.                                         case 0:    /* Do disk test */
  775.                                             Do_Disk_Test(Window);
  776.                                             break;
  777.                                         case 1:    /* Save result file */
  778.                                             Save_To_File(Window);
  779.                                             break;
  780.                                         case 2:    /* Print result file */
  781.                                             Save_To_Printer(Window);
  782.                                             break;
  783.                                         case 3:    /* Quit... */
  784.                                             QuitFlag=TRUE;
  785.                                             break;
  786.                                         }
  787.                                     }
  788.                                     thismenu=ItemAddress(&MyMenu,(long)thismenu)->NextSelect;
  789.                                 }
  790.                                 SetWindowTitles(Window,WindowText,WindowText);
  791.                                 SetMenuStrip(Window,&MyMenu);
  792.                                 OnGadget(&MyGadget,Window,NULL);
  793.                             }
  794.                             ReplyMsg((struct Message *)msg);
  795.                         }
  796.                     }
  797.                     ClearMenuStrip(Window);
  798.                     CloseWindow(Window);
  799.                 }
  800.                 CloseDevice((struct IORequest *)Time_Req);
  801.             }
  802.             CloseLibrary((struct Library *)IntuitionBase);
  803.         }
  804.         FreeMem(Time_Req,sizeof(struct timerequest));
  805.     }
  806.     pr->pr_WindowPtr=Old_WindowPtr;
  807. }
  808.